home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / IO.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  36KB  |  1,688 lines

  1. /* source/io.c: terminal I/O code, uses the curses package
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #include <stdio.h>
  10. #ifndef STDIO_LOADED
  11. #define STDIO_LOADED
  12. #endif
  13.  
  14. #include "config.h"
  15.  
  16. #if defined(atarist) && defined(__GNUC__)
  17. #include <osbind.h>
  18. #endif
  19.  
  20. #ifdef MSDOS
  21. #include <process.h>
  22. #endif
  23.  
  24. #ifdef AMIGA
  25. /* detach from cli process */
  26. long _stack = 30000;
  27. long _priority = 0;
  28. long _BackGroundIO = 1;
  29. char *_procname = "Moria";
  30. #endif
  31.  
  32. #if defined(NLS) && defined(lint)
  33. /* for AIX, don't let curses include the NL stuff */
  34. #undef NLS
  35. #endif
  36.  
  37. #if !defined(GEMDOS)
  38. #ifdef MAC
  39. #ifdef THINK_C
  40. #include "ScrnMgr.h"
  41. #else
  42. #include <scrnmgr.h>
  43. #endif
  44. #else
  45. #include <curses.h>
  46. #endif
  47. #else    /* GEMDOS i.e. Atari ST */
  48. #include "curses.h"
  49. long wgetch();
  50. #ifdef ATARIST_TC
  51. #include <tos.h>    /* TC */
  52. #include <ext.h>
  53. #else
  54. #include <osbind.h>    /* MWC */
  55. #endif
  56. char *getenv();
  57. #endif
  58.  
  59. /* These are included after curses.h to avoid redefintion warnings for
  60.    TRUE, FALSE, and NULL.  */
  61.  
  62. #include "constant.h"
  63. #include "types.h"
  64. #include "externs.h"
  65.  
  66. #include <ctype.h>
  67.  
  68. #if defined(SYS_V) && defined(lint)
  69. /* for AIX, prevent hundreds of unnecessary lint errors, must define before
  70.    signal.h is included */
  71. #define _h_IEEETRAP
  72. typedef struct { int stuff; } fpvmach;
  73. #endif
  74.  
  75. #if defined(MSDOS)
  76. #if defined(ANSI)
  77. #include "ms_ansi.h"
  78. #endif
  79. #else /* not msdos */
  80. #if !defined(ATARI_ST) && !defined(MAC) && !defined(AMIGA)
  81. #ifndef VMS
  82. #include <sys/ioctl.h>
  83. #endif
  84. #include <signal.h>
  85. #endif
  86. #endif
  87.  
  88. #ifndef USG
  89. /* only needed for Berkeley UNIX */
  90. #include <sys/param.h>
  91. #include <sys/file.h>
  92. #include <sys/types.h>
  93. #endif
  94.  
  95. #ifdef USG
  96. #ifndef ATARI_ST
  97. #include <string.h>
  98. #else
  99. #include "string.h"
  100. #endif
  101. #if 0
  102. /* Used to include termio.h here, but that caused problems on some systems,
  103.    as curses.h includes it also above.  */
  104. #if !defined(MAC) && !defined(MSDOS) && !defined(ATARI_ST)
  105. #if !defined(AMIGA) && !defined(VMS)
  106. #include <termio.h>
  107. #endif
  108. #endif
  109. #endif
  110. #else /* ! USG */
  111. #include <strings.h>
  112. #if defined(atarist) && defined(__GNUC__)
  113. /* doesn't have sys/wait.h */
  114. #else
  115. #include <sys/wait.h>
  116. #endif
  117. #endif
  118.  
  119. #ifdef ATARIST_TC
  120. /* Include this to get prototypes for standard library functions.  */
  121. #include <stdlib.h>
  122. #endif
  123.  
  124. #if defined(SYS_V) && defined(lint)
  125. struct screen { int dumb; };
  126. #endif
  127.  
  128. /* Fooling lint. Unfortunately, c defines all the TIO.      -CJS-
  129.    constants to be long, and lint expects them to be int. Also,
  130.    ioctl is sometimes called with just two arguments. The
  131.    following definition keeps lint happy. It may need to be
  132.    reset for different systems.     */
  133. #ifndef MAC
  134. #ifdef lint
  135. #ifdef Pyramid
  136. /* Pyramid makes constants greater than 65535 into long! Gakk! -CJS- */
  137. /*ARGSUSED*/
  138. /*VARARGS2*/
  139. static Ioctl(i, l, p) long l; char *p; { return 0; }
  140. #else
  141. /*ARGSUSED*/
  142. /*VARARGS2*/
  143. static Ioctl(i, l, p) char *p; { return 0; }
  144. #endif
  145. #define ioctl        Ioctl
  146. #endif
  147.  
  148. #if !defined(USG) && defined(lint)
  149. /* This use_value hack is for curses macros which return a value,
  150.    but don't shut up about it when you try to tell them (void).     */
  151. /* only needed for Berkeley UNIX */
  152. int Use_value;
  153. #define use_value   Use_value +=
  154. #else
  155. #define use_value
  156. #endif
  157.  
  158. #if defined(SYS_V) && defined(lint)
  159. /* This use_value2 hack is for curses macros which use a conditional
  160.    expression, and which say null effect even if you cast to (void). */
  161. /* only needed for SYS V */
  162. int Use_value2;
  163. #define use_value2  Use_value2 +=
  164. #else
  165. #define use_value2
  166. #endif
  167.  
  168. #endif
  169.  
  170. #ifndef MAC
  171. char *getenv();
  172. #endif
  173.  
  174. #ifndef VMS
  175. #ifdef USG
  176. void exit();
  177. #if defined(__TURBOC__)
  178. void sleep();
  179. #else
  180. #ifndef AMIGA
  181. unsigned sleep();
  182. #endif
  183. #endif
  184. #endif
  185. #endif
  186.  
  187. #ifdef ultrix
  188. void exit();
  189. void sleep();
  190. #endif
  191.  
  192. #if !defined(MAC) && !defined(MSDOS) && !defined(ATARI_ST) && !defined(VMS)
  193. #ifndef AMIGA
  194. #ifdef USG
  195. static struct termio save_termio;
  196. #else
  197. static struct ltchars save_special_chars;
  198. static struct sgttyb save_ttyb;
  199. static struct tchars save_tchars;
  200. static int save_local_chars;
  201. #endif
  202. #endif
  203. #endif
  204.  
  205. #ifndef MAC
  206. static int curses_on = FALSE;
  207. static WINDOW *savescr;        /* Spare window for saving the screen. -CJS-*/
  208. #ifdef VMS
  209. static WINDOW *tempscr;        /* Spare window for VMS CTRL('R'). */
  210. #endif
  211. #endif
  212.  
  213. #ifdef MAC
  214. /* Attributes of normal and hilighted characters */
  215. #define ATTR_NORMAL    attrNormal
  216. #define ATTR_HILITED    attrReversed
  217. #endif
  218.  
  219. #ifndef MAC
  220. #ifdef SIGTSTP
  221. /* suspend()                               -CJS-
  222.    Handle the stop and start signals. This ensures that the log
  223.    is up to date, and that the terminal is fully reset and
  224.    restored.  */
  225. int suspend()
  226. {
  227. #ifdef USG
  228.   /* for USG systems with BSDisms that have SIGTSTP defined, but don't
  229.      actually implement it */
  230. #else
  231.   struct sgttyb tbuf;
  232.   struct ltchars lcbuf;
  233.   struct tchars cbuf;
  234.   int lbuf;
  235.   long time();
  236.  
  237.   py.misc.male |= 2;
  238.   (void) ioctl(0, TIOCGETP, (char *)&tbuf);
  239.   (void) ioctl(0, TIOCGETC, (char *)&cbuf);
  240.   (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
  241. #if !defined(atarist) && !defined(__GNUC__)
  242.   (void) ioctl(0, TIOCLGET, (char *)&lbuf);
  243. #endif
  244.   restore_term();
  245.   (void) kill(0, SIGSTOP);
  246.   curses_on = TRUE;
  247.   (void) ioctl(0, TIOCSETP, (char *)&tbuf);
  248.   (void) ioctl(0, TIOCSETC, (char *)&cbuf);
  249.   (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
  250. #if !defined(atarist) && !defined(__GNUC__)
  251.   (void) ioctl(0, TIOCLSET, (char *)&lbuf);
  252. #endif
  253.   (void) wrefresh(curscr);
  254.   py.misc.male &= ~2;
  255. #endif
  256.   return 0;
  257. }
  258. #endif
  259. #endif
  260.  
  261. /* initializes curses routines */
  262. void init_curses()
  263. #ifdef MAC
  264. {
  265.   /* Primary initialization is done in mac.c since game is restartable */
  266.   /* Only need to clear the screen here */
  267.   Rect scrn;
  268.  
  269.   scrn.left = scrn.top = 0;
  270.   scrn.right = SCRN_COLS;
  271.   scrn.bottom = SCRN_ROWS;
  272.   EraseScreen(&scrn);
  273.   UpdateScreen();
  274. }
  275. #else
  276. {
  277.   int i, y, x;
  278.  
  279. #ifdef AMIGA
  280.   if (opentimer() == 0)
  281.     {
  282.       (void) printf ("Could not open timer device.\n");
  283.       exit (1);
  284.     }
  285. #endif
  286.  
  287. #ifndef USG
  288.   (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
  289.   (void) ioctl(0, TIOCGETP, (char *)&save_ttyb);
  290.   (void) ioctl(0, TIOCGETC, (char *)&save_tchars);
  291. #if !defined(atarist) && !defined(__GNUC__)
  292.   (void) ioctl(0, TIOCLGET, (char *)&save_local_chars);
  293. #endif
  294. #else
  295. #if !defined(VMS) && !defined(MSDOS) && !defined(ATARI_ST)
  296. #ifndef AMIGA
  297.   (void) ioctl(0, TCGETA, (char *)&save_termio);
  298. #endif
  299. #endif
  300. #endif
  301.  
  302.   /* PC curses returns ERR */
  303. #if defined(USG) && !defined(PC_CURSES) && !defined(AMIGA)
  304.   if (initscr() == NULL)
  305. #else
  306.   if (initscr() == ERR)
  307. #endif
  308.     {
  309.       (void) printf("Error allocating screen in curses package.\n");
  310.       exit(1);
  311.     }
  312.   if (LINES < 24 || COLS < 80)     /* Check we have enough screen. -CJS- */
  313.     {
  314.       (void) printf("Screen too small for moria.\n");
  315.       exit (1);
  316.     }
  317. #ifdef SIGTSTP
  318. #if defined(atarist) && defined(__GNUC__)
  319.   (void) signal (SIGTSTP, (__Sigfunc)suspend);
  320. #else
  321.   (void) signal (SIGTSTP, suspend);
  322. #endif
  323. #endif
  324.   if (((savescr = newwin (0, 0, 0, 0)) == NULL)
  325. #ifdef VMS
  326.       || ((tempscr = newwin (0, 0, 0, 0)) == NULL))
  327. #else
  328.     )
  329. #endif
  330.     {
  331.       (void) printf ("Out of memory in starting up curses.\n");
  332.       exit_game();
  333.     }
  334.   (void) clear();
  335.   (void) refresh();
  336.   moriaterm ();
  337.  
  338. #if 0
  339.   /* This assumes that the terminal is 80 characters wide, which is not
  340.      guaranteed to be true.  */
  341.  
  342.   /* check tab settings, exit with error if they are not 8 spaces apart */
  343.   (void) move(0, 0);
  344.   for (i = 1; i < 10; i++)
  345.     {
  346.       (void) addch('\t');
  347.       getyx(stdscr, y, x);
  348.       if (y != 0 || x != i*8)
  349.     break;
  350.     }
  351.   if (i != 10)
  352.     {
  353.       msg_print("Tabs must be set 8 spaces apart.");
  354.       exit_game();
  355.     }
  356. #endif
  357. }
  358. #endif
  359.  
  360. /* Set up the terminal into a suitable state for moria.     -CJS- */
  361. void moriaterm()
  362. #ifdef MAC
  363. /* Nothing to do on Mac */
  364. {
  365. }
  366. #else
  367. {
  368. #if !defined(MSDOS) && !defined(ATARI_ST) && !defined(VMS)
  369. #ifndef AMIGA
  370. #ifdef USG
  371.   struct termio tbuf;
  372. #else
  373.   struct ltchars lbuf;
  374.   struct tchars buf;
  375. #endif
  376. #endif
  377. #endif
  378.  
  379.   curses_on = TRUE;
  380. #ifndef BSD4_3
  381.   use_value crmode();
  382. #else
  383. #ifdef VMS
  384.   use_value vms_crmode ();
  385. #else
  386.   use_value cbreak();
  387. #endif
  388. #endif
  389.   use_value noecho();
  390.   /* can not use nonl(), because some curses do not handle it correctly */
  391. #ifdef MSDOS
  392.   msdos_raw();
  393. #else
  394. #ifdef AMIGA
  395.   init_color (0,   0,   0,   0);    /* pen 0 - black */
  396.   init_color (1,1000,1000,1000);    /* pen 1 - white */
  397.   init_color (2,   0, 300, 700);    /* pen 2 - blue */
  398.   init_color (3,1000, 500,   0);    /* pen 3 - orange */
  399. #else
  400. #if !defined(ATARI_ST) && !defined(VMS)
  401. #ifdef USG
  402.   (void) ioctl(0, TCGETA, (char *)&tbuf);
  403.   /* disable all of the normal special control characters */
  404.   tbuf.c_cc[VINTR] = (char)3; /* control-C */
  405.   tbuf.c_cc[VQUIT] = (char)-1;
  406.   tbuf.c_cc[VERASE] = (char)-1;
  407.   tbuf.c_cc[VKILL] = (char)-1;
  408.   tbuf.c_cc[VEOF] = (char)-1;
  409.  
  410.   /* don't know what these are for */
  411.   tbuf.c_cc[VEOL] = (char)-1;
  412. #ifdef VEOL2
  413.   tbuf.c_cc[VEOL2] = (char)-1;
  414. #endif
  415.  
  416.   /* stuff needed when !icanon, i.e. cbreak/raw mode */
  417.   tbuf.c_cc[VMIN] = 1;  /* Input should wait for at least 1 char */
  418.   tbuf.c_cc[VTIME] = 0; /* no matter how long that takes. */
  419.  
  420.   (void) ioctl(0, TCSETA, (char *)&tbuf);
  421. #else
  422.   /* disable all of the special characters except the suspend char, interrupt
  423.      char, and the control flow start/stop characters */
  424.   (void) ioctl(0, TIOCGLTC, (char *)&lbuf);
  425.   lbuf.t_suspc = (char)26; /* control-Z */
  426.   lbuf.t_dsuspc = (char)-1;
  427.   lbuf.t_rprntc = (char)-1;
  428.   lbuf.t_flushc = (char)-1;
  429.   lbuf.t_werasc = (char)-1;
  430.   lbuf.t_lnextc = (char)-1;
  431.   (void) ioctl(0, TIOCSLTC, (char *)&lbuf);
  432.  
  433.   (void) ioctl (0, TIOCGETC, (char *)&buf);
  434.   buf.t_intrc = (char)3; /* control-C */
  435.   buf.t_quitc = (char)-1;
  436.   buf.t_startc = (char)17; /* control-Q */
  437.   buf.t_stopc = (char)19; /* control-S */
  438.   buf.t_eofc = (char)-1;
  439.   buf.t_brkc = (char)-1;
  440.   (void) ioctl(0, TIOCSETC, (char *)&buf);
  441. #endif
  442. #endif
  443. #endif
  444. #endif
  445.  
  446. #ifdef ATARIST_TC
  447.   raw ();
  448. #endif
  449. }
  450. #endif
  451.  
  452.  
  453. /* Dump IO to buffer                    -RAK-    */
  454. void put_buffer(out_str, row, col)
  455. char *out_str;
  456. int row, col;
  457. #ifdef MAC
  458. {
  459.   /* The screen manager handles writes past the edge ok */
  460.   DSetScreenCursor(col, row);
  461.   DWriteScreenStringAttr(out_str, ATTR_NORMAL);
  462. }
  463. #else
  464. {
  465.   vtype tmp_str;
  466.  
  467.   /* truncate the string, to make sure that it won't go past right edge of
  468.      screen */
  469.   if (col > 79)
  470.     col = 79;
  471.   (void) strncpy (tmp_str, out_str, 79 - col);
  472.   tmp_str [79 - col] = '\0';
  473.  
  474.   if (mvaddstr(row, col, tmp_str) == ERR)
  475.     {
  476.       abort();
  477.       /* clear msg_flag to avoid problems with unflushed messages */
  478.       msg_flag = 0;
  479.       (void) sprintf(tmp_str, "error in put_buffer, row = %d col = %d\n",
  480.              row, col);
  481.       prt(tmp_str, 0, 0);
  482.       bell();
  483.       /* wait so user can see error */
  484.       (void) sleep(2);
  485.     }
  486. }
  487. #endif
  488.  
  489.  
  490. /* Dump the IO buffer to terminal            -RAK-    */
  491. void put_qio()
  492. {
  493.   screen_change = TRUE;       /* Let inven_command know something has changed. */
  494. #ifdef MAC
  495.   UpdateScreen();
  496. #else
  497.   (void) refresh();
  498. #endif
  499. }
  500.  
  501. /* Put the terminal in the original mode.               -CJS- */
  502. void restore_term()
  503. #ifdef MAC
  504. /* Nothing to do on Mac */
  505. {
  506. }
  507. #else
  508. {
  509. #ifdef AMIGA
  510.   closetimer ();
  511. #endif
  512.  
  513.   if (!curses_on)
  514.     return;
  515.   put_qio();  /* Dump any remaining buffer */
  516. #ifdef MSDOS
  517.   (void) sleep(2);   /* And let it be read. */
  518. #endif
  519. #ifdef VMS
  520.   clear_screen();
  521.   pause_line(15);
  522. #endif
  523.   /* this moves curses to bottom right corner */
  524.   mvcur(stdscr->_cury, stdscr->_curx, LINES-1, 0);
  525.   endwin();  /* exit curses */
  526.   (void) fflush (stdout);
  527. #ifdef MSDOS
  528.   msdos_noraw();
  529. #endif
  530.   /* restore the saved values of the special chars */
  531. #ifdef USG
  532. #if !defined(MSDOS) && !defined(ATARI_ST) && !defined(VMS)
  533. #ifndef AMIGA
  534.   (void) ioctl(0, TCSETA, (char *)&save_termio);
  535. #endif
  536. #endif
  537. #else
  538.   (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  539.   (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
  540.   (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
  541. #if !defined(atarist) && !defined(__GNUC__)
  542.   (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
  543. #endif
  544. #endif
  545.   curses_on = FALSE;
  546. }
  547. #endif
  548.  
  549.  
  550. void shell_out()
  551. #if defined(atarist) && defined(__GNUC__)
  552. { char fail_message[80], arg_list[1], *p;
  553.   int  escape_code;
  554.  
  555.   save_screen();
  556.   clear_screen();
  557.   use_value nocbreak();         /* Must remember to reset terminal modes   */
  558.   use_value echo();             /* or shell i/o will be quite messed up!   */
  559.  
  560.   p = (char *)getenv("SHELL");
  561.   if (p != (char *)NULL)
  562.     { put_buffer("Escaping to Shell\n",0,0);
  563.       put_qio();
  564.       arg_list[0]=0;
  565.       escape_code = Pexec(0,p,arg_list,0);   /* Launch the shell.          */
  566.  
  567.       if (escape_code != 0)
  568.          { sprintf(fail_message,"Pexec() error code = %d\n",escape_code);
  569.            put_buffer(fail_message,0,0);
  570.            put_qio();
  571.        sleep(5);
  572.      }
  573.     }
  574.   use_value cbreak();        /* Reset the terminal back to CBREAK/NOECHO   */
  575.   use_value noecho();
  576.   clear_screen();            /* Do not want shell data on screen.          */
  577.   restore_screen();
  578. }
  579.  
  580. #else
  581.  
  582. #ifdef MAC
  583. {
  584.   alert_error("This command is not implemented on the Macintosh.");
  585. }
  586. #else
  587. #if defined(AMIGA) || defined(ATARIST_TC)
  588. {
  589.   put_buffer("This command is not implemented.\n", 0, 0);
  590. }
  591. #else
  592. #ifdef VMS /* TPP */
  593. {
  594.   int val, istat;
  595.   char *str;
  596.  
  597.   save_screen();
  598.   /* clear screen and print 'exit' message */
  599.   clear_screen();
  600.   put_buffer("[Entering subprocess, type 'EOJ' to resume your game.]\n",
  601.          0, 0);
  602.   put_qio();
  603.  
  604.   use_value vms_nocrmode();
  605.   use_value echo();
  606.   ignore_signals();
  607.  
  608.   istat = lib$spawn();
  609.   if (!istat)
  610.     lib$signal (istat);
  611.  
  612.   restore_signals();
  613.   use_value vms_crmode();
  614.   use_value noecho();
  615.   /* restore the cave to the screen */
  616.   restore_screen();
  617.   put_buffer("Welcome back to UMoria.\n", 0, 0);
  618.   save_screen();
  619.   clear_screen();
  620.   put_qio();
  621.   restore_screen();
  622.   (void) wrefresh(curscr);
  623. }
  624. #else
  625. {
  626. #ifdef USG
  627. #if !defined(MSDOS) && !defined(ATARI_ST) && !defined(AMIGA)
  628.   struct termio tbuf;
  629. #endif
  630. #else
  631.   struct sgttyb tbuf;
  632.   struct ltchars lcbuf;
  633.   struct tchars cbuf;
  634.   int lbuf;
  635. #endif
  636. #ifdef MSDOS
  637.   char    *comspec, key;
  638. #else
  639. #ifdef ATARI_ST
  640.   char comstr[80];
  641.   char *str;
  642.   extern char **environ;
  643. #else
  644.   int val;
  645.   char *str;
  646. #endif
  647. #endif
  648.  
  649.   save_screen();
  650.   /* clear screen and print 'exit' message */
  651.   clear_screen();
  652. #ifndef ATARI_ST
  653.   put_buffer("[Entering shell, type 'exit' to resume your game.]\n",0,0);
  654. #else
  655.   put_buffer("[Escaping to shell]\n",0,0);
  656. #endif
  657.   put_qio();
  658.  
  659. #ifdef USG
  660. #if !defined(MSDOS) && !defined(ATARI_ST) && !defined(AMIGA)
  661.   (void) ioctl(0, TCGETA, (char *)&tbuf);
  662. #endif
  663. #else
  664.   (void) ioctl(0, TIOCGETP, (char *)&tbuf);
  665.   (void) ioctl(0, TIOCGETC, (char *)&cbuf);
  666.   (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
  667.   (void) ioctl(0, TIOCLGET, (char *)&lbuf);
  668. #endif
  669.   /* would call nl() here if could use nl()/nonl(), see moriaterm() */
  670. #ifndef BSD4_3
  671.   use_value nocrmode();
  672. #else
  673. #ifdef VMS
  674.   use_value vms_nocrmode ();
  675. #else
  676.   use_value nocbreak();
  677. #endif
  678. #endif
  679. #ifdef MSDOS
  680.   use_value msdos_noraw();
  681. #endif
  682.   use_value echo();
  683.   ignore_signals();
  684. #ifdef MSDOS        /*{*/
  685.   if ((comspec = getenv("COMSPEC")) == CNIL
  686.   ||  spawnl(P_WAIT, comspec, comspec, CNIL) < 0) {
  687.     clear_screen();    /* BOSS key if shell failed */
  688.     put_buffer("M:\\> ", 0, 0);
  689.     do {
  690.       key = inkey();
  691.     } while (key != '!');
  692.   }
  693.  
  694. #else        /* MSDOS }{*/
  695. #ifndef ATARI_ST
  696.   val = fork();
  697.   if (val == 0)
  698.     {
  699. #endif
  700.       default_signals();
  701. #ifdef USG
  702. #if !defined(MSDOS) && !defined(ATARI_ST) && !defined(AMIGA)
  703.       (void) ioctl(0, TCSETA, (char *)&save_termio);
  704. #endif
  705. #else
  706.       (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  707.       (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
  708.       (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
  709.       (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
  710. #endif
  711. #ifndef MSDOS
  712.       /* close scoreboard descriptor */
  713.       /* it is not open on MSDOS machines */
  714.       (void) fclose(highscore_fp);
  715. #endif
  716.       if (str = getenv("SHELL"))
  717. #ifndef ATARI_ST
  718.     (void) execl(str, str, (char *) 0);
  719. #else
  720.     system(str);
  721. #endif
  722.       else
  723. #ifndef ATARI_ST
  724.     (void) execl("/bin/sh", "sh", (char *) 0);
  725. #endif
  726.       msg_print("Cannot execute shell.");
  727. #ifndef ATARI_ST
  728.       exit(1);
  729.     }
  730.   if (val == -1)
  731.     {
  732.       msg_print("Fork failed. Try again.");
  733.       return;
  734.     }
  735. #ifdef USG
  736.   (void) wait((int *) 0);
  737. #else
  738.   (void) wait((union wait *) 0);
  739. #endif
  740. #endif /* ATARI_ST */
  741. #endif         /* MSDOS }*/
  742.   restore_signals();
  743.   /* restore the cave to the screen */
  744.   restore_screen();
  745. #ifndef BSD4_3
  746.   use_value crmode();
  747. #else
  748. #ifdef VMS
  749.   use_value vms_crmode ();
  750. #else
  751.   use_value cbreak();
  752. #endif
  753. #endif
  754.   use_value noecho();
  755.   /* would call nonl() here if could use nl()/nonl(), see moriaterm() */
  756. #ifdef MSDOS
  757.   msdos_raw();
  758. #endif
  759.   /* disable all of the local special characters except the suspend char */
  760.   /* have to disable ^Y for tunneling */
  761. #ifdef USG
  762. #if !defined(MSDOS) && !defined(ATARI_ST)
  763.   (void) ioctl(0, TCSETA, (char *)&tbuf);
  764. #endif
  765. #else
  766.   (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
  767.   (void) ioctl(0, TIOCSETP, (char *)&tbuf);
  768.   (void) ioctl(0, TIOCSETC, (char *)&cbuf);
  769.   (void) ioctl(0, TIOCLSET, (char *)&lbuf);
  770. #endif
  771.   (void) wrefresh(curscr);
  772. }
  773. #endif
  774. #endif
  775. #endif
  776. #endif
  777.  
  778. /* Returns a single character input from the terminal.    This silently -CJS-
  779.    consumes ^R to redraw the screen and reset the terminal, so that this
  780.    operation can always be performed at any input prompt.  inkey() never
  781.    returns ^R.    */
  782. char inkey()
  783. #ifdef MAC
  784. /* The Mac does not need ^R, so it just consumes it */
  785. /* This routine does nothing special with direction keys */
  786. /* Just returns their keypad ascii value (e.g. '0'-'9') */
  787. /* Compare with inkeydir() below */
  788. {
  789.   char ch;
  790.   int dir;
  791.   int shift_flag, ctrl_flag;
  792.  
  793.   put_qio();
  794.   command_count = 0;
  795.  
  796.   do {
  797.     macgetkey(&ch, FALSE);
  798.   } while (ch == CTRL('R'));
  799.  
  800.   dir = extractdir(ch, &shift_flag, &ctrl_flag);
  801.   if (dir != -1)
  802.     ch = '0' + dir;
  803.  
  804.   return(ch);
  805. }
  806. #else
  807. {
  808.   int i;
  809. #ifdef VMS
  810.   vtype tmp_str;
  811. #endif
  812.  
  813.   put_qio();            /* Dump IO buffer        */
  814.   command_count = 0;  /* Just to be safe -CJS- */
  815.   while (TRUE)
  816.     {
  817. #ifdef MSDOS
  818.       i = msdos_getch();
  819. #else
  820. #ifdef VMS
  821.       i = vms_getch ();
  822. #else
  823.       i = getch();
  824. #if defined(atarist) && defined(__GNUC__)
  825. /* for some reason a keypad number produces an initial negative number. */
  826.       if (i<0) i = getch();
  827. #endif
  828. #endif
  829. #endif
  830.  
  831. #ifdef VMS
  832.       if (i == 27) /* if ESCAPE key, then we probably have a keypad key */
  833.     {
  834.       i = vms_getch();
  835.       if (i == 'O') /* Now it is definitely a numeric keypad key */
  836.         {
  837.           i = vms_getch();
  838.           switch (i)
  839.         {
  840.           case 'p': i = '0'; break;
  841.           case 'q' : i = '1'; break;
  842.           case 'r' : i = '2'; break;
  843.           case 's' : i = '3'; break;
  844.           case 't' : i = '4'; break;
  845.           case 'u' : i = '5'; break;
  846.           case 'v' : i = '6'; break;
  847.           case 'w' : i = '7'; break;
  848.           case 'x' : i = '8'; break;
  849.           case 'y' : i = '9'; break;
  850.           case 'm' : i = '-'; break;
  851.           case 'M' : i = 10; break; /* Enter = RETURN */
  852.           case 'n' : i = '.'; break;
  853.           default : while (kbhit()) (void) vms_getch();
  854.           }
  855.         }
  856.       else
  857.         {
  858.           while (kbhit())
  859.         (void) vms_getch();
  860.         }
  861.     }
  862. #endif /* VMS */
  863.  
  864.       /* some machines may not sign extend. */
  865.       if (i == EOF)
  866.     {
  867.       eof_flag++;
  868.       /* avoid infinite loops while trying to call inkey() for a -more-
  869.          prompt. */
  870.       msg_flag = FALSE;
  871.  
  872.       (void) refresh ();
  873.       if (!character_generated || character_saved)
  874.         exit_game();
  875.       disturb(1, 0);
  876.       if (eof_flag > 100)
  877.         {
  878.           /* just in case, to make sure that the process eventually dies */
  879.           panic_save = 1;
  880.           (void) strcpy(died_from, "(end of input: panic saved)");
  881.           if (!save_char())
  882.         {
  883.           (void) strcpy(died_from, "panic: unexpected eof");
  884.           death = TRUE;
  885.         }
  886.           exit_game();
  887.         }
  888.       return ESCAPE;
  889.     }
  890.       if (i != CTRL('R'))
  891.     return (char)i;
  892. #ifdef VMS
  893.       /* Refresh does not work right under VMS, so use a brute force. */
  894.       overwrite (stdscr, tempscr);
  895.       clear_screen();
  896.       put_qio();
  897.       overwrite (tempscr, stdscr);
  898.       touchwin (stdscr);
  899.       (void) wrefresh (stdscr);
  900. #endif
  901.       (void) wrefresh (curscr);
  902.       moriaterm();
  903.     }
  904. }
  905. #endif
  906.  
  907.  
  908. #ifdef MAC
  909. char inkeydir()
  910. /* The Mac does not need ^R, so it just consumes it */
  911. /* This routine translates the direction keys in rogue-like mode */
  912. /* Compare with inkeydir() below */
  913. {
  914.   char ch;
  915.   int dir;
  916.   int shift_flag, ctrl_flag;
  917.   static char tab[9] = {
  918.     'b',        'j',        'n',
  919.     'h',        '.',        'l',
  920.     'y',        'k',        'u'
  921.   };
  922.   static char shifttab[9] = {
  923.     'B',        'J',        'N',
  924.     'H',        '.',        'L',
  925.     'Y',        'K',        'U'
  926.   };
  927.   static char ctrltab[9] = {
  928.     CTRL('B'),    CTRL('J'),    CTRL('N'),
  929.     CTRL('H'),    '.',        CTRL('L'),
  930.     CTRL('Y'),    CTRL('K'),    CTRL('U')
  931.   };
  932.  
  933.   put_qio();
  934.   command_count = 0;
  935.  
  936.   do {
  937.     macgetkey(&ch, FALSE);
  938.   } while (ch == CTRL('R'));
  939.  
  940.   dir = extractdir(ch, &shift_flag, &ctrl_flag);
  941.  
  942.   if (dir != -1) {
  943.     if (!rogue_like_commands) {
  944.       ch = '0' + dir;
  945.     }
  946.     else {
  947.       if (ctrl_flag)
  948.     ch = ctrltab[dir - 1];
  949.       else if (shift_flag)
  950.     ch = shifttab[dir - 1];
  951.       else
  952.     ch = tab[dir - 1];
  953.     }
  954.   }
  955.  
  956.   return(ch);
  957. }
  958. #endif
  959.  
  960.  
  961. /* Flush the buffer                    -RAK-    */
  962. void flush()
  963. #ifdef MAC
  964. {
  965. /* Removed put_qio() call.  Reduces flashing.  Doesn't seem to hurt. */
  966.   FlushScreenKeys();
  967. }
  968. #else
  969. {
  970. #if defined(MSDOS)
  971.   while (kbhit())
  972.     (void) getch();
  973. #else
  974. #ifdef VMS
  975.   while (kbhit ())
  976.     (void) vms_getch();
  977. #else
  978.   /* the code originally used ioctls, TIOCDRAIN, or TIOCGETP/TIOCSETP, or
  979.      TCGETA/TCSETAF, however this occasionally resulted in loss of output,
  980.      the happened especially often when rlogin from BSD to SYS_V machine,
  981.      using check_input makes the desired effect a bit clearer */
  982.   /* wierd things happen on EOF, don't try to flush input in that case */
  983.   if (!eof_flag)
  984.     while (check_input(0));
  985. #endif
  986. #endif
  987.  
  988.   /* used to call put_qio() here to drain output, but it is not necessary */
  989. }
  990. #endif
  991.  
  992.  
  993. /* Clears given line of text                -RAK-    */
  994. void erase_line(row, col)
  995. int row;
  996. int col;
  997. #ifdef MAC
  998. {
  999.   Rect line;
  1000.  
  1001.   if (row == MSG_LINE && msg_flag)
  1002.     msg_print(CNIL);
  1003.  
  1004.   line.left = col;
  1005.   line.top = row;
  1006.   line.right = SCRN_COLS;
  1007.   line.bottom = row + 1;
  1008.   DEraseScreen(&line);
  1009. }
  1010. #else
  1011. {
  1012.   if (row == MSG_LINE && msg_flag)
  1013.     msg_print(CNIL);
  1014.   (void) move(row, col);
  1015.   clrtoeol();
  1016. }
  1017. #endif
  1018.  
  1019.  
  1020. /* Clears screen */
  1021. void clear_screen()
  1022. #ifdef MAC
  1023. {
  1024.   Rect area;
  1025.  
  1026.   if (msg_flag)
  1027.     msg_print(CNIL);
  1028.  
  1029.   area.left = area.top = 0;
  1030.   area.right = SCRN_COLS;
  1031.   area.bottom = SCRN_ROWS;
  1032.   DEraseScreen(&area);
  1033. }
  1034. #else
  1035. {
  1036.   if (msg_flag)
  1037.     msg_print(CNIL);
  1038. #ifdef VMS
  1039.   /* Clear doesn't work right under VMS, so use brute force. */
  1040.   (void) clearok (stdscr, TRUE);
  1041.   (void) wclear(stdscr);
  1042.   (void) clearok (stdscr, FALSE);
  1043. #else
  1044.   (void) clear();
  1045. #endif
  1046. }
  1047. #endif
  1048.  
  1049. void clear_from (row)
  1050. int row;
  1051. #ifdef MAC
  1052. {
  1053.   Rect area;
  1054.  
  1055.   area.left = 0;
  1056.   area.top = row;
  1057.   area.right = SCRN_COLS;
  1058.   area.bottom = SCRN_ROWS;
  1059.   DEraseScreen(&area);
  1060. }
  1061. #else
  1062. {
  1063.   (void) move(row, 0);
  1064.   clrtobot();
  1065. }
  1066. #endif
  1067.  
  1068.  
  1069. /* Outputs a char to a given interpolated y, x position    -RAK-    */
  1070. /* sign bit of a character used to indicate standout mode. -CJS */
  1071. void print(ch, row, col)
  1072. char ch;
  1073. int row;
  1074. int col;
  1075. #ifdef MAC
  1076. {
  1077.   char cnow, anow;
  1078.  
  1079.   row -= panel_row_prt;/* Real co-ords convert to screen positions */
  1080.   col -= panel_col_prt;
  1081.  
  1082.   GetScreenCharAttr(&cnow, &anow, col, row);    /* Check current */
  1083.  
  1084.   /* If char is already set, ignore op */
  1085.   if ((cnow != ch) || (anow != ATTR_NORMAL))
  1086.     DSetScreenCharAttr(ch & 0x7F,
  1087.                (ch & 0x80) ? attrReversed : attrNormal,
  1088.                col, row);
  1089. }
  1090. #else
  1091. {
  1092.   vtype tmp_str;
  1093.  
  1094.   row -= panel_row_prt;/* Real co-ords convert to screen positions */
  1095.   col -= panel_col_prt;
  1096.   if (mvaddch (row, col, ch) == ERR)
  1097.     {
  1098.       abort();
  1099.       /* clear msg_flag to avoid problems with unflushed messages */
  1100.       msg_flag = 0;
  1101.       (void) sprintf(tmp_str, "error in print, row = %d col = %d\n",
  1102.              row, col);
  1103.       prt(tmp_str, 0, 0);
  1104.       bell ();
  1105.       /* wait so user can see error */
  1106.       (void) sleep(2);
  1107.     }
  1108. }
  1109. #endif
  1110.  
  1111.  
  1112. /* Moves the cursor to a given interpolated y, x position    -RAK-    */
  1113. void move_cursor_relative(row, col)
  1114. int row;
  1115. int col;
  1116. #ifdef MAC
  1117. {
  1118.   row -= panel_row_prt;/* Real co-ords convert to screen positions */
  1119.   col -= panel_col_prt;
  1120.  
  1121.   DSetScreenCursor(col, row);
  1122. }
  1123. #else
  1124. {
  1125.   vtype tmp_str;
  1126.  
  1127.   row -= panel_row_prt;/* Real co-ords convert to screen positions */
  1128.   col -= panel_col_prt;
  1129.   if (move (row, col) == ERR)
  1130.     {
  1131.       abort();
  1132.       /* clear msg_flag to avoid problems with unflushed messages */
  1133.       msg_flag = 0;
  1134.       (void) sprintf(tmp_str,
  1135.              "error in move_cursor_relative, row = %d col = %d\n",
  1136.              row, col);
  1137.       prt(tmp_str, 0, 0);
  1138.       bell();
  1139.       /* wait so user can see error */
  1140.       (void) sleep(2);
  1141.     }
  1142. }
  1143. #endif
  1144.  
  1145.  
  1146. /* Print a message so as not to interrupt a counted command. -CJS- */
  1147. void count_msg_print(p)
  1148. char *p;
  1149. {
  1150.   int i;
  1151.  
  1152.   i = command_count;
  1153.   msg_print(p);
  1154.   command_count = i;
  1155. }
  1156.  
  1157.  
  1158. /* Outputs a line to a given y, x position        -RAK-    */
  1159. void prt(str_buff, row, col)
  1160. char *str_buff;
  1161. int row;
  1162. int col;
  1163. #ifdef MAC
  1164. {
  1165.   Rect line;
  1166.  
  1167.   if (row == MSG_LINE && msg_flag)
  1168.     msg_print(CNIL);
  1169.  
  1170.   line.left = col;
  1171.   line.top = row;
  1172.   line.right = SCRN_COLS;
  1173.   line.bottom = row + 1;
  1174.   DEraseScreen(&line);
  1175.  
  1176.   put_buffer(str_buff, row, col);
  1177. }
  1178. #else
  1179. {
  1180.   if (row == MSG_LINE && msg_flag)
  1181.     msg_print(CNIL);
  1182.   (void) move(row, col);
  1183.   clrtoeol();
  1184.   put_buffer(str_buff, row, col);
  1185. }
  1186. #endif
  1187.  
  1188.  
  1189. /* move cursor to a given y, x position */
  1190. void move_cursor(row, col)
  1191. int row, col;
  1192. #ifdef MAC
  1193. {
  1194.   DSetScreenCursor(col, row);
  1195. }
  1196. #else
  1197. {
  1198.   (void) move (row, col);
  1199. }
  1200. #endif
  1201.  
  1202.  
  1203. /* Outputs message to top line of screen                */
  1204. /* These messages are kept for later reference.     */
  1205. void msg_print(str_buff)
  1206. char *str_buff;
  1207. {
  1208.   register int old_len, new_len;
  1209.   int combine_messages = FALSE;
  1210.   char in_char;
  1211. #ifdef MAC
  1212.   Rect line;
  1213. #endif
  1214.  
  1215.   if (msg_flag)
  1216.     {
  1217.       old_len = strlen(old_msg[last_msg]) + 1;
  1218.  
  1219.       /* If the new message and the old message are short enough, we want
  1220.      display them together on the same line.  So we don't flush the old
  1221.      message in this case.  */
  1222.      
  1223.       if (str_buff)
  1224.     new_len = strlen (str_buff);
  1225.       else
  1226.     new_len = 0;
  1227.  
  1228.       if (! str_buff || (new_len + old_len + 2 >= 73))
  1229.     {
  1230.       /* ensure that the complete -more- message is visible. */
  1231.       if (old_len > 73)
  1232.         old_len = 73;
  1233.       put_buffer(" -more-", MSG_LINE, old_len);
  1234.       /* let sigint handler know that we are waiting for a space */
  1235.       wait_for_more = 1;
  1236.       do
  1237.         {
  1238.           in_char = inkey();
  1239.         }
  1240.       while ((in_char != ' ') && (in_char != ESCAPE) && (in_char != '\n')
  1241.          && (in_char != '\r'));
  1242.       wait_for_more = 0;
  1243.     }
  1244.       else
  1245.     combine_messages = TRUE;
  1246.     }
  1247.  
  1248.   if (! combine_messages)
  1249.     {
  1250. #ifdef MAC
  1251.       line.left = 0;
  1252.       line.top = MSG_LINE;
  1253.       line.right = SCRN_COLS;
  1254.       line.bottom = MSG_LINE+1;
  1255.       DEraseScreen(&line);
  1256. #else
  1257.       (void) move(MSG_LINE, 0);
  1258.       clrtoeol();
  1259. #endif
  1260.     }
  1261.  
  1262.   /* Make the null string a special case.  -CJS- */
  1263.   if (str_buff)
  1264.     {
  1265.       command_count = 0;
  1266.       msg_flag = TRUE;
  1267.  
  1268.       /* If the new message and the old message are short enough, display
  1269.      them on the same line.  */
  1270.       
  1271.       if (combine_messages)
  1272.     {
  1273.       put_buffer (str_buff, MSG_LINE, old_len + 2);
  1274.       strcat (old_msg[last_msg], "  ");
  1275.       strcat (old_msg[last_msg], str_buff);
  1276.     }
  1277.       else
  1278.     {
  1279.       put_buffer(str_buff, MSG_LINE, 0);
  1280.       last_msg++;
  1281.       if (last_msg >= MAX_SAVE_MSG)
  1282.         last_msg = 0;
  1283.       (void) strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
  1284.       old_msg[last_msg][VTYPESIZ - 1] = '\0';
  1285.     }
  1286.     }
  1287.   else
  1288.     msg_flag = FALSE;
  1289. }
  1290.  
  1291.  
  1292. /* Used to verify a choice - user gets the chance to abort choice.  -CJS- */
  1293. int get_check(prompt)
  1294. char *prompt;
  1295. {
  1296.   int res;
  1297. #ifdef MAC
  1298.   long y, x;        /* ??? Should change to int or short.  */
  1299. #else
  1300.   int y, x;
  1301. #endif
  1302.  
  1303.   prt(prompt, 0, 0);
  1304. #ifdef MAC
  1305.   GetScreenCursor(&x, &y);
  1306. #else
  1307.   getyx(stdscr, y, x);
  1308. #if defined(lint)
  1309.   /* prevent message 'warning: y is unused' */
  1310.   x = y;
  1311. #endif
  1312. #ifdef LINT_ARGS
  1313.   /* prevent message about y never used for MSDOS systems */
  1314.   res = y;
  1315. #endif
  1316. #endif
  1317.  
  1318.   if (x > 73)
  1319.     (void) move(0, 73);
  1320. #ifdef MAC
  1321.   DWriteScreenStringAttr(" [y/n]", ATTR_NORMAL);
  1322. #else
  1323.   (void) addstr(" [y/n]");
  1324. #endif
  1325.   do
  1326.     {
  1327.       res = inkey();
  1328.     }
  1329.   while(res == ' ');
  1330.   erase_line(0, 0);
  1331.   if (res == 'Y' || res == 'y')
  1332.     return TRUE;
  1333.   else
  1334.     return FALSE;
  1335. }
  1336.  
  1337. /* Prompts (optional) and returns ord value of input char    */
  1338. /* Function returns false if <ESCAPE> is input    */
  1339. int get_com(prompt, command)
  1340. char *prompt;
  1341. char *command;
  1342. {
  1343.   int res;
  1344.  
  1345.   if (prompt)
  1346.     prt(prompt, 0, 0);
  1347.   *command = inkey();
  1348.   if (*command == ESCAPE)
  1349.     res = FALSE;
  1350.   else
  1351.     res = TRUE;
  1352.   erase_line(MSG_LINE, 0);
  1353.   return(res);
  1354. }
  1355.  
  1356. #ifdef MAC
  1357. /* Same as get_com(), but translates direction keys from keypad */
  1358. int get_comdir(prompt, command)
  1359. char *prompt;
  1360. char *command;
  1361. {
  1362.   int res;
  1363.  
  1364.   if (prompt)
  1365.     prt(prompt, 0, 0);
  1366.   *command = inkeydir();
  1367.   if (*command == ESCAPE)
  1368.     res = FALSE;
  1369.   else
  1370.     res = TRUE;
  1371.   erase_line(MSG_LINE, 0);
  1372.   return(res);
  1373. }
  1374. #endif
  1375.  
  1376.  
  1377. /* Gets a string terminated by <RETURN>        */
  1378. /* Function returns false if <ESCAPE> is input    */
  1379. int get_string(in_str, row, column, slen)
  1380. char *in_str;
  1381. int row, column, slen;
  1382. {
  1383.   register int start_col, end_col, i;
  1384.   char *p;
  1385.   int flag, aborted;
  1386. #ifdef MAC
  1387.   Rect area;
  1388. #endif
  1389.  
  1390.   aborted = FALSE;
  1391.   flag    = FALSE;
  1392. #ifdef MAC
  1393.   area.left = column;
  1394.   area.top = row;
  1395.   area.right = column + slen;
  1396.   area.bottom = row + 1;
  1397.   DEraseScreen(&area);
  1398.   DSetScreenCursor(column, row);
  1399. #else
  1400.   (void) move(row, column);
  1401.   for (i = slen; i > 0; i--)
  1402.     (void) addch(' ');
  1403.   (void) move(row, column);
  1404. #endif
  1405.   start_col = column;
  1406.   end_col = column + slen - 1;
  1407.   if (end_col > 79)
  1408.     {
  1409.       slen = 80 - column;
  1410.       end_col = 79;
  1411.     }
  1412.   p = in_str;
  1413.   do
  1414.     {
  1415.       i = inkey();
  1416.       switch(i)
  1417.     {
  1418.     case ESCAPE:
  1419.       aborted = TRUE;
  1420.       break;
  1421.     case CTRL('J'): case CTRL('M'):
  1422.       flag    = TRUE;
  1423.       break;
  1424.     case DELETE: case CTRL('H'):
  1425.       if (column > start_col)
  1426.         {
  1427.           column--;
  1428.           put_buffer(" ", row, column);
  1429.           move_cursor(row, column);
  1430.           *--p = '\0';
  1431.         }
  1432.       break;
  1433.     default:
  1434.       if (!isprint(i) || column > end_col)
  1435.         bell();
  1436.       else
  1437.         {
  1438. #ifdef MAC
  1439.           DSetScreenCursor(column, row);
  1440.           DWriteScreenCharAttr((char) i, ATTR_NORMAL);
  1441. #else
  1442.           use_value2 mvaddch(row, column, (char)i);
  1443. #endif
  1444.           *p++ = i;
  1445.           column++;
  1446.         }
  1447.       break;
  1448.     }
  1449.     }
  1450.   while ((!flag) && (!aborted));
  1451.   if (aborted)
  1452.     return(FALSE);
  1453.   /* Remove trailing blanks    */
  1454.   while (p > in_str && p[-1] == ' ')
  1455.     p--;
  1456.   *p = '\0';
  1457.   return(TRUE);
  1458. }
  1459.  
  1460.  
  1461. /* Pauses for user response before returning        -RAK-    */
  1462. void pause_line(prt_line)
  1463. int prt_line;
  1464. {
  1465.   prt("[Press any key to continue.]", prt_line, 23);
  1466.   (void) inkey();
  1467.   erase_line(prt_line, 0);
  1468. }
  1469.  
  1470.  
  1471. /* Pauses for user response before returning        -RAK-    */
  1472. /* NOTE: Delay is for players trying to roll up "perfect"    */
  1473. /*    characters.  Make them wait a bit.            */
  1474. void pause_exit(prt_line, delay)
  1475. int prt_line;
  1476. int delay;
  1477. {
  1478.   char dummy;
  1479.  
  1480.   prt("[Press any key to continue, or Q to exit.]", prt_line, 10);
  1481.   dummy = inkey();
  1482.   if (dummy == 'Q')
  1483.     {
  1484.       erase_line(prt_line, 0);
  1485. #ifndef MSDOS        /* PCs are slow enough as is  -dgk */
  1486.       if (delay > 0)  (void) sleep((unsigned)delay);
  1487. #else
  1488.       /* prevent message about delay unused */
  1489.       dummy = delay;
  1490. #endif
  1491. #ifdef MAC
  1492.       enablefilemenu(FALSE);
  1493.       exit_game();
  1494.       enablefilemenu(TRUE);
  1495. #else
  1496.       exit_game();
  1497. #endif
  1498.     }
  1499.   erase_line(prt_line, 0);
  1500. }
  1501.  
  1502. #ifdef MAC
  1503. void save_screen()
  1504. {
  1505.   mac_save_screen();
  1506. }
  1507.  
  1508. void restore_screen()
  1509. {
  1510.   mac_restore_screen();
  1511. }
  1512. #else
  1513. void save_screen()
  1514. {
  1515.   overwrite(stdscr, savescr);
  1516. }
  1517.  
  1518. void restore_screen()
  1519. {
  1520.   overwrite(savescr, stdscr);
  1521.   touchwin(stdscr);
  1522. }
  1523. #endif
  1524.  
  1525. void bell()
  1526. {
  1527.   put_qio();
  1528.  
  1529.   /* The player can turn off beeps if he/she finds them annoying.  */
  1530.   if (! sound_beep_flag)
  1531.     return;
  1532.  
  1533. #ifdef MAC
  1534.   mac_beep();
  1535. #else
  1536.   (void) write(1, "\007", 1);
  1537. #endif
  1538. }
  1539.  
  1540. /* definitions used by screen_map() */
  1541. /* index into border character array */
  1542. #define TL 0    /* top left */
  1543. #define TR 1
  1544. #define BL 2
  1545. #define BR 3
  1546. #define HE 4    /* horizontal edge */
  1547. #define VE 5
  1548.  
  1549. /* character set to use */
  1550. #ifdef MSDOS
  1551. # ifdef ANSI
  1552. #   define CH(x)    (ansi ? screen_border[0][x] : screen_border[1][x])
  1553. # else
  1554. #   define CH(x)    (screen_border[1][x])
  1555. # endif
  1556. #else
  1557. #   define CH(x)    (screen_border[0][x])
  1558. #endif
  1559.  
  1560.   /* Display highest priority object in the RATIO by RATIO area */
  1561. #define    RATIO 3
  1562.  
  1563. void screen_map()
  1564. {
  1565.   register int    i, j;
  1566.   static int8u screen_border[2][6] = {
  1567.     {'+', '+', '+', '+', '-', '|'},    /* normal chars */
  1568.     {201, 187, 200, 188, 205, 186}    /* graphics chars */
  1569.   };
  1570.   int8u map[MAX_WIDTH / RATIO + 1];
  1571.   int8u tmp;
  1572.   int priority[256];
  1573.   int row, orow, col, myrow, mycol = 0;
  1574. #ifndef MAC
  1575.   char prntscrnbuf[80];
  1576. #endif
  1577.  
  1578.   for (i = 0; i < 256; i++)
  1579.     priority[i] = 0;
  1580.   priority['<'] = 5;
  1581.   priority['>'] = 5;
  1582.   priority['@'] = 10;
  1583. #ifdef MSDOS
  1584.   priority[wallsym] = -5;
  1585.   priority[floorsym] = -10;
  1586. #else
  1587. #ifndef ATARI_ST
  1588.   priority['#'] = -5;
  1589. #else
  1590.   priority[(unsigned char)240] = -5;
  1591. #endif
  1592.   priority['.'] = -10;
  1593. #endif
  1594.   priority['\''] = -3;
  1595.   priority[' '] = -15;
  1596.  
  1597.   save_screen();
  1598.   clear_screen();
  1599. #ifdef MAC
  1600.   DSetScreenCursor(0, 0);
  1601.   DWriteScreenCharAttr(CH(TL), ATTR_NORMAL);
  1602.   for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1603.     DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
  1604.   DWriteScreenCharAttr(CH(TR), ATTR_NORMAL);
  1605. #else
  1606.   use_value2 mvaddch(0, 0, CH(TL));
  1607.   for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1608.     (void) addch(CH(HE));
  1609.   (void) addch(CH(TR));
  1610. #endif
  1611.   orow = -1;
  1612.   map[MAX_WIDTH / RATIO] = '\0';
  1613.   for (i = 0; i < MAX_HEIGHT; i++)
  1614.     {
  1615.       row = i / RATIO;
  1616.       if (row != orow)
  1617.     {
  1618.       if (orow >= 0)
  1619.         {
  1620. #ifdef MAC
  1621.           DSetScreenCursor(0, orow+1);
  1622.           DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1623.           DWriteScreenString((char *) map);
  1624.           DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1625. #else
  1626.           /* can not use mvprintw() on ibmpc, because PC-Curses is horribly
  1627.          written, and mvprintw() causes the fp emulation library to be
  1628.          linked with PC-Moria, makes the program 10K bigger */
  1629.           (void) sprintf(prntscrnbuf,"%c%s%c",CH(VE), map, CH(VE));
  1630.           use_value2 mvaddstr(orow+1, 0, prntscrnbuf);
  1631. #endif
  1632.         }
  1633.       for (j = 0; j < MAX_WIDTH / RATIO; j++)
  1634.         map[j] = ' ';
  1635.       orow = row;
  1636.     }
  1637.       for (j = 0; j < MAX_WIDTH; j++)
  1638.     {
  1639.       col = j / RATIO;
  1640.       tmp = loc_symbol(i, j);
  1641.       if (priority[map[col]] < priority[tmp])
  1642.         map[col] = tmp;
  1643.       if (map[col] == '@')
  1644.         {
  1645.           mycol = col + 1; /* account for border */
  1646.           myrow = row + 1;
  1647.         }
  1648.     }
  1649.     }
  1650.   if (orow >= 0)
  1651.     {
  1652. #ifdef MAC
  1653.       DSetScreenCursor(0, orow+1);
  1654.       DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1655.       DWriteScreenString((char *) map);
  1656.       DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1657. #else
  1658.       (void) sprintf(prntscrnbuf,"%c%s%c",CH(VE), map, CH(VE));
  1659.       use_value2 mvaddstr(orow+1, 0, prntscrnbuf);
  1660. #endif
  1661.     }
  1662. #ifdef MAC
  1663.   DSetScreenCursor(0, orow + 2);
  1664.   DWriteScreenCharAttr(CH(BL), ATTR_NORMAL);
  1665.   for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1666.     DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
  1667.   DWriteScreenCharAttr(CH(BR), ATTR_NORMAL);
  1668. #else
  1669.   use_value2 mvaddch(orow + 2, 0, CH(BL));
  1670.   for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1671.     (void) addch(CH(HE));
  1672.   (void) addch(CH(BR));
  1673. #endif
  1674.  
  1675. #ifdef MAC
  1676.   DSetScreenCursor(23, 23);
  1677.   DWriteScreenStringAttr("Hit any key to continue", ATTR_NORMAL);
  1678.   if (mycol > 0)
  1679.     DSetScreenCursor(mycol, myrow);
  1680. #else
  1681.   use_value2 mvaddstr(23, 23, "Hit any key to continue");
  1682.   if (mycol > 0)
  1683.     (void) move(myrow, mycol);
  1684. #endif
  1685.   (void) inkey();
  1686.   restore_screen();
  1687. }
  1688.